from django import template
from django.template.defaultfilters import stringfilter
from django.core.urlresolvers import reverse
from django.utils.html import escape
import re

register = template.Library()

RE_WIK_LINK      = re.compile(r'\[\[\s*(?P<path>(?:\w|[\-\/.])+?)(?:/)?\s*\]\]', re.MULTILINE)
RE_WIK_EMPHASIZE = re.compile('(?<!\\&amp;)\\&amp;(?!\\&amp;)(?P<text>[^\n\\&]*?)(?<!\\&amp;)\\&amp;(?!\\&amp;)', re.MULTILINE)
RE_WIK_STRONG    = re.compile('(?<!\\*)\\*(?!\\*)(?P<text>[^\n\\*]*?)(?<!\\*)\\*(?!\\*)', re.MULTILINE)
RE_WIK_HEADER    = re.compile('(?:^|(?:\n*))\s*h(\\d)\.([^\n]*)(?:\n*)', re.MULTILINE)
RE_WIK_DELETE    = re.compile('(?<!-)-(?!-)(?P<text>[^\n-]*?)(?<!-)-(?!-)', re.MULTILINE)
RE_WIK_INSERT    = re.compile('(?<!_)_(?!_)(?P<text>[^\n_]*?)(?<!_)_(?!_)', re.MULTILINE)
RE_WIK_HEADER    = re.compile('(?:^|(?:\n*))h(\\d)\.([^\n]*)(?:\n*)', re.MULTILINE)
RE_WIK_DIV       = re.compile(r'(?:^|\n|\>)\s*[#]([a-zA-Z]+)[^\n]*\n(.*?)(?:\n|\>)\s*[#]\s*(?:\n|$)', re.DOTALL)

def wik_safe(value):
    return escape(value)

wiks = [wik_safe]

def wikfunc(f):
    wiks.append(f)

def wik_unsymbol(value):
    return value.replace('*', '**').replace('-', '--').replace('&amp;', '&amp;&amp;').replace('_', '__')

@wikfunc
def wik_div(value):
    def subwik(match):
        div_class = match.group(1)
        text = match.group(2)
        return '<div class="%s">%s</div>' % (div_class, text.strip(' \n'))
    
    count = 1
    while count > 0:
        value, count = RE_WIK_DIV.subn(subwik, value)
    return value
    

@wikfunc
def wik_link(value):
    def subwik(match):
        path = match.group(1)
        url = reverse('wiki_view', kwargs={'path':path})
        return '<a href="%s">%s</a>' % (wik_unsymbol(url), wik_unsymbol(path))
    return RE_WIK_LINK.sub(subwik, value)

@wikfunc
def wik_emphasize(value):
    def subwik(match):
        text = match.group(1)
        return '<em>%s</em>' % text
    return RE_WIK_EMPHASIZE.sub(subwik, value)

@wikfunc
def wik_strong(value):
    def subwik(match):
        text = match.group(1)
        return '<strong>%s</strong>' % text
    return RE_WIK_STRONG.sub(subwik, value)

@wikfunc
def wik_header(value):
    def subwik(match):
        header_number = match.group(1)
        text = match.group(2)
        return '<h%s>%s</h%s>' % (header_number, text, header_number)
    return RE_WIK_HEADER.sub(subwik, value)

@wikfunc
def wik_delete(value):
    def subwik(match):
        text = match.group(1)
        return '<del>%s</del>' % text
    return RE_WIK_DELETE.sub(subwik, value)

@wikfunc
def wik_insert(value):
    def subwik(match):
        text = match.group(1)
        return '<ins>%s</ins>' % text
    return RE_WIK_INSERT.sub(subwik, value)

@wikfunc
def wik_symbols(value):
    return value.replace('**', '*').replace('--', '-').replace('&amp;&amp;', '&amp;').replace('__', '_')

@register.filter
@stringfilter
def wik(value):
    for wik_func in wiks:
        value = wik_func(value)
    return value
wik.is_safe = True
